import json
from datetime import datetime

from django.http import JsonResponse, HttpResponseBadRequest
from django.shortcuts import render
from decimal import Decimal
# Create your views here.
from django_redis import get_redis_connection
from rest_framework.views import APIView

from apps.goods.models import SKU
from apps.orders.models import OrderInfo, OrderGoods
from apps.user.models import Address


class OrderSettlementView(APIView):
    def get(self, request):
        user = request.user

        adds = Address.objects.filter(is_deleted=False, user_id=user.id)

        addresses_list = []

        for address in adds:
            addresses_list.append({
                "id": address.id,
                "province": address.province.name,
                'city': address.city.name,
                'district': address.district.name,
                'place': address.place,
                'receiver': address.receiver,
                'mobile': address.mobile
            })

        redis_conn = get_redis_connection("carts")

        carts_dict = redis_conn.hgetall("cart_%s" % user.id)
        selected_list = redis_conn.smembers('selected_%s' % user.id)

        new_cart_dict = {}
        for sku_id in selected_list:
            count = carts_dict[sku_id]

            new_cart_dict[int(sku_id)] = int(count)

        try:
            skus = SKU.objects.filter(id__in=new_cart_dict.keys())
        except Exception as e:
            print(e)
            return JsonResponse({'code': 400, 'errmsg': '数据查询失败'})

        sku_list = []
        for sku in skus:
            sku_list.append({
                "id": sku.id,
                "name": sku.name,
                # "default_image_url": sku.default_image.url,
                "count": new_cart_dict[sku.id],
                "price": sku.price,

            })

        freight = Decimal('10.00')
        context = {
            "addresses": addresses_list,
            "skus": sku_list,
            "freight": freight,
        }

        return JsonResponse({'code': 0, 'errmsg': 'ok', 'context': context})
    def post(self, request):
        user = request.user

        json_data = json.loads(request.body)

        address_id = json_data.get('address_id')

        pay_method = json_data.get('pay_method')

        if not all([address_id, pay_method]):
            return HttpResponseBadRequest('缺少必传参数')

        try:
            address = Address.objects.get(id=address_id)

        except Exception as e:
            print(e)
            return HttpResponseBadRequest('参数address_id错误')

            # 判断pay_method是否合法
        if pay_method not in {OrderInfo.PAY_METHODS_ENUM['CASH'], OrderInfo.PAY_METHODS_ENUM['ALIPAY']}:
            return HttpResponseBadRequest('参数pay_method错误')

        # order_id = timezone.localtime().strftime('%Y%m%d%H%M%S%f') + ('%9d' % user.id)
        order_id = datetime.now().strftime('%Y%m%d%H%M%S%f') + ('%09d' % user.id)



        # print(order_id)
        total_count = 0

        total_amount = 0

        freight = Decimal('10.00')

        status = OrderInfo.ORDER_STATUS_ENUM['UNPAID'] if pay_method == OrderInfo.PAY_METHODS_ENUM['ALIPAY'] else \
            OrderInfo.ORDER_STATUS_ENUM['UNSEND']

        from django.db import transaction
        with transaction.atomic():  # 开启事务
            save_id = transaction.savepoint()

            try:
                order = OrderInfo.objects.create(
                    order_id=order_id,
                    user=user,
                    address_id=address_id,
                    total_count=total_count,
                    total_amount=total_amount,
                    freight=freight,
                    pay_method=pay_method,
                    status=status
                )
            except Exception as e:
                print(e)
                return JsonResponse({'code': 400, 'errmsg': "创建失败"})

        redis_conn = get_redis_connection('carts')

        carts_dict = redis_conn.hgetall('cart_%s' % user.id)

        selected_list = redis_conn.smembers('selected_%s' % user.id)

        new_cart_dict = {}

        for sku_id in selected_list:
            count = carts_dict[sku_id]

            new_cart_dict[int(sku_id)] = int(count)

        try:
            skus = SKU.objects.filter(id__in=new_cart_dict.keys())

        except Exception as e:
            print(e)
            # 回滚到保存点
            transaction.savepoint_rollback(save_id)
            return JsonResponse({'code': 400, "errmsg": "数据查询失败"})

        try:
            for sku in skus:

                while True:

                    origin_stock = sku.stock
                    origin_sales = sku.sales
                    count = new_cart_dict[sku.id]

                    if count > sku.stock:
                        transaction.savepoint_rollback(save_id)
                        return JsonResponse({'code': 400, 'errmsg': "库存不足"})


                    new_stock = origin_stock - count
                    new_sales = origin_sales + count

                    result = SKU.objects.filter(id=sku.id, stock=origin_stock).update(stock=new_stock, sales=new_sales)

                    if result ==0:
                        continue

                    OrderGoods.objects.create(
                        order_id=order_id,
                        sku=sku,
                        count=count,
                        price=sku.price
                    )

                    order.total_count += count

                    order.total_amount += count * sku.price
                    break
            order.total_amount += order.freight

            order.save()
            print("保存 成功")
        except Exception as e:
            print(e)
            # 回滚到保存点
            transaction.savepoint_rollback(save_id)
            return JsonResponse({'code': 400, 'errmsg': '保存失败'})
        transaction.savepoint_commit(save_id)

        pl = redis_conn.pipeline()
        pl.hdel('cart_%s' % user.id, *selected_list)
        pl.srem('selected_%s' % user.id, *selected_list)
        pl.execute()

        # 响应提交订单结果
        return JsonResponse({'code': 0, 'errmsg': '下单成功', 'order_id': order_id})